nsbase.utility = new function() {
    // / <field name="errorDialog" type="String">Show error message with a
    // 'close' button.</field>
    // / <field name="promptDialog" type="String">Show prompt message with a
    // 'close' button</field>
    // / <field name="confirmDialog" type="String">Show confirm message with
    // 'confirm' and 'canel' button, and you need to supply the event
    // handler</field>

    var _self = this;
    function _init() {
        _self.toJsonString = toJsonString;
        _self.toJson = toJson;
        _self.htmlEncode = htmlEncode;
        _self.htmlDecode = htmlDecode;
        // The regex to match mvc style date string, i.e. /Date(1324990982128)/
        _self.mvcDateRegex = new RegExp(/\/Date\(\d+\)\//gi);
        // The regex to match standard date string, i.e. 2011/12/27
        _self.standardDateRegex = new RegExp(/^(\d{2}|\d{4})\/\d{2}\/\d{2}$/gi);
        _self.getNextMonthDate = getNextMonthDate;
        _self.getMonthDates = getMonthDates;
        _self.getDate = getDate;
        _self.toUTCDate = toUTCDate;
        _self.toDate = toDate;
        _self.toStandardDateString = toStandardDateString;
        _self.toStandardDateTimeString = toStandardDateTimeString;
        _self.toMvcDateString = toMvcDateString;
        _self.dateFormat = dateFormat;
        _self.isMaxDate = isMaxDate;
        _self.getCurrencySymbol = getCurrencySymbol;
        _self.getQueryParams = getQueryParams;
        _self.padLeft = padLeft;
        _self.trim = trim;
        _self.trimStart = trimStart;
        _self.trimEnd = trimEnd;
        _self.getStringLength = getStringLength;
        _self.subString = subString;
        _self.stringFormat = stringFormat;
        _self.tmplFormat = tmplFormat;
        _self.wordLengthCounter = wordLengthCounter;
        _self.getBackgroundImage = getBackgroundImage;
        _self.errorDialog = errorDialog;
        _self.promptDialog = promptDialog;
        _self.confirmDialog = confirmDialog;
 
    }

    function errorDialog(message) {
        var divDialog = $("#divErrorDialog");
        if (divDialog.length == 0) {
            divDialog = $("<div id='divErrorDialog' style='display: none;font-size:16px;'><span></span><br /></div>");
            $(".main").append(divDialog);
        }
        divDialog.find("span").html(message);
        var config = {
            modal : true,
            resizable : false,
            buttons : {},
            title : "友情提示!"
        };
        config.buttons["关闭"] = function() {
            $(this).dialog("close");
        };
        divDialog.dialog(config);
    };

    function promptDialog(message, title) {
        var divDialog = $("#divPromptDialog");
        divDialog.empty();
        if (divDialog.length == 0) {
            divDialog = $("<div id='divPromptDialog' style='display: none;font-size:16px;'><span></span><br /></div>");
            $(".main").append(divDialog);
        }
        //divDialog.find("span").html(message);
        divDialog.append(message);
        var config = {
            modal : true,
            resizable : false,
            buttons : {},
            title : title || "友情提示!"
        };
        config.buttons["关闭"] = function() {
            $(this).dialog("close");
        };
        divDialog.dialog(config);
    };
    

    function confirmDialog(message, confirmHandler, canelHandler, title) {
        var divDialog = $("#divConfirmDialog");
        if (divDialog.length == 0) {
            divDialog = $("<div id='divConfirmDialog' style='display: none;font-size:16px;'></div>");
            $("body").append(divDialog);
        }
        divDialog.html(message);
        var config = {
            modal : true,
            resizable : false,
            buttons : {},
            title : title || "确认提交?"
        };
        config.buttons["确认"] = function(){
            confirmHandler();
            $(this).dialog("close");
        };
        if (canelHandler) {
            config.buttons["取消"] = canelHandler;
        } else {
            config.buttons["取消"] = function() {
                $(this).dialog("close");
            };
        }
        divDialog.dialog(config);
    };

    function htmlEncode(str) {
        return str.replace(/&/g, '&amp;').replace(/\"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
    };
    function htmlDecode(str) {
        return str.replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&quot;/g, '"');
    };

    function toJsonString(obj) {
        return JSON.stringify(obj);
    }

    function toJson(jsonString) {
        if (jsonString == "") {
            jsonString = null;
        }
        return JSON.parse(jsonString);
    };

    function getNextMonthDate() {
        var now = new Date();
        return new Date(now.setMonth(now.getMonth() + 1));
    };

    function getMonthDates (year,month) {
        if(!year){
            year = new Date().getFullYear();
        }
        if(!month){
            month = new Date().getMonth();
        }
        var monthStartDate = new Date(year,month,1);
        var monthEndDate = new Date(year,month+1);
        var dates = (monthEndDate - monthStartDate)/(1000*60*60*24);
        return dates;
    }
    function toUTCDate(dateStr) {
        var date = toDate(dateStr);
        var time = date.getTime();
        var utcTime = time - date.getTimezoneOffset() * 60 * 1000;
        return new Date(utcTime);
    };

    function toDate(dateStr) {
        // / <summary>
        // / Convert date string into Date object.
        // / </summary>
        // / <param name="dateStr" type="String">The date string.</param>
        // / <returns type="Date">The Date object.</returns>
        if (typeof dateStr == "string") {
            dateStr = dateStr.replace(/-/g,'/');
            if (dateStr.match(_self.standardDateRegex) != null) {
                return new Date(Date.parse(dateStr));
            } else if (dateStr.match(_self.mvcDateRegex) != null) {
                var ticks = parseInt(dateStr.replace(/\/Date\((\d+)\)\//gim,"$1"));
                return new Date(ticks);
            } else {
                return new Date(Date.parse(dateStr));
            }
        } else if (nsbase.utility.functions.isDate(dateStr)) {
            return dateStr;
        }
        return new Date(Date.parse(dateStr));
    };

    function toStandardDateString(dateStr, dateDelimiter) {
        // / <summary>
        // / Convert mvc style date string into standard style.
        // / </summary>
        // / <param name="dateStr" type="String">The date string.</param>
        // / <param name="dateDelimiter" type="String">The character to separate
        // year,month and day,eg:"/" or "-"</param>
        // / <returns type="String">The standard format of date
        // string.</returns>
        var date = dateStr;
        if (!nsbase.utility.functions.isDate(dateStr)) {
            date = toDate(dateStr);
        }
        dateDelimiter = dateDelimiter || "/";
        if (!isNaN(date)) {
            return date.getFullYear() + dateDelimiter
            + padLeft((date.getMonth() + 1), 2, "0") + dateDelimiter
            + padLeft(date.getDate(), 2, "0");
        } else {
            return dateStr;
        }
    };

    function getDate(day){
        if(!day){
            day = 0;
        } 
        var zdate = new Date();
        var sdate = zdate.getTime()-(1*24*60*60*1000);
        var edate = new Date(sdate+(day*24*60*60*1000));
        return edate;
    }
    function toStandardDateTimeString(dateStr, dateDelimiter) {
        // / <summary>
        // / Convert mvc style date string into standard style.
        // / </summary>
        // / <param name="dateStr" type="Date">The date string.</param>
        // / <param name="dateDelimiter" type="String">The character to separate
        // year,month and day,eg:"/" or "-"</param>
        // / <returns type="String">The standard format of date
        // string.</returns>
        var date = dateStr;
        if (!nsbase.utility.functions.isDate(dateStr)) {
            date = toDate(dateStr);
        }
        if (!isNaN(date)) {
            return toStandardDateString(dateStr, dateDelimiter) + " "
            + padLeft(date.getHours(), 2, "0") + ":"
            + padLeft(date.getMinutes(), 2, "0") + ":"
            + padLeft(date.getSeconds(), 2, "0");
        } else {
            return dateStr;
        }
    };

    function toMvcDateString(dateStr) {
        // / <summary>
        // / Convert a date object or date string to MVC style date string.
        // / </summary>
        // / <param name="dateStr">The date value.</param>
        // / <returns>The MVC style of date string.</returns>
        var date = dateStr;
        if (!nsbase.utility.functions.isDate(dateStr)) {
            date = toDate(dateStr);
        }
        if (!isNaN(date)) {
            var dateTime = date.getTime();
            return '\/Date(' + dateTime + ')\/';
        } else {
            return dateStr;
        }
    };

    function dateFormat(dateStr, format) {
        var date = toDate(dateStr);
        var o = {
            "M+" : date.getMonth() + 1, // month
            "d+" : date.getDate(), // day
            "h+" : date.getHours(), // hour
            "m+" : date.getMinutes(), // minute
            "s+" : date.getSeconds(), // second
            "q+" : Math.floor((date.getMonth() + 3) / 3), // quarter
            "S" : date.getMilliseconds()
        // millisecond
        }
        if (/(y+)/.test(format)) {
            format = format.replace(RegExp.$1, (date.getFullYear() + "")
                .substr(4 - RegExp.$1.length));
        }
        for ( var k in o) {
            if (new RegExp("(" + k + ")").test(format)) {
                format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k]
                    : ("00" + o[k]).substr(("" + o[k]).length));
            }
        }
        return format;
    };

    function isMaxDate(dateValue) {
        var date = toDate(dateValue);
        if (!isNaN(date)) {
            return (date.getFullYear() >= 9999);
        }
        return false;
    };

    function padLeft(str, totalWidth, padChar) {
        var builder = [];
        if (!str) {
            str = "";
        }
        if (typeof str != "string") {
            str = str.toString();
        }
        if (!padChar) {
            padChar = " "; // space char
        }
        if (typeof padChar != "string") {
            padChar = padChar.toString();
        }
        builder.push(str);
        var count = str.length;
        while (count < totalWidth) {
            builder.unshift(padChar);
            count += padChar.length;
        }
        return builder.join("");
    };
    
    function trim(string) {
        // /<returns type="String"/>
        return string.replace(/^\s+|\s+$/g, "");
    };

    function trimEnd(string,char){
        var r = new RegExp("^\s+|\s*" + char + "$");
        return string.replace(r, "");
    }

    function trimStart(string,char){
        var r = new RegExp("^\s*"+char);
        return string.replace(r, "");
    }

    function getCurrencySymbol(currency) {
        var currencyEnum;
        if (nsbase.enums.Currency.isEnum(currency)) {
            currencyEnum = currency;
        } else {
            currencyEnum = nsbase.enums.Currency.getEnumByKey(currency);
        }
        switch (currencyEnum) {
            case nsbase.enums.Currency.CNY:
                return "\u00a5"; // ¥
            case nsbase.enums.Currency.USD:
                return "\u0024"; // $
            case nsbase.enums.Currency.HKD:
                return "\u0024"; // $
            case nsbase.enums.Currency.KPW:
                return "\u20a9"; // ₩
            case nsbase.enums.Currency.VND:
                return "\u20ab"; // ₫
            case nsbase.enums.Currency.JPY:
                return "\u00a5"; // ¥
            case nsbase.enums.Currency.LAK:
                return "\u20ad"; // ₭
            case nsbase.enums.Currency.KHR:
                return "\u17db"; // ៛
            case nsbase.enums.Currency.PHP:
                return "\u0050\u0068\u0070"; // Php
            case nsbase.enums.Currency.MYR:
                return "\u0052\u004d"; // RM
            case nsbase.enums.Currency.SGD:
                return "\u0024"; // $
            case nsbase.enums.Currency.LKR:
                return "\u20a8"; // ₨
            case nsbase.enums.Currency.IDR:
                return "\u0052\u0070"; // Rp
            case nsbase.enums.Currency.NPR:
                return "\u20a8"; // ₨
            case nsbase.enums.Currency.IRR:
                return "\ufdfc"; // ﷼
            case nsbase.enums.Currency.SYP:
                return "\u00a3"; // £
            case nsbase.enums.Currency.LBP:
                return "\u00a3"; // £
            case nsbase.enums.Currency.SAR:
                return "\ufdfc"; // ﷼
            case nsbase.enums.Currency.QAR:
                return "\ufdfc"; // ﷼
            case nsbase.enums.Currency.OMR:
                return "\ufdfc"; // ﷼
            case nsbase.enums.Currency.YER:
                return "\ufdfc"; // ﷼
            case nsbase.enums.Currency.TRL:
                return "\u20a4"; // ₤
            case nsbase.enums.Currency.EUR:
                return "\u20ac"; // €
            case nsbase.enums.Currency.ISK:
                return "\u006b\u0072"; // kr
            case nsbase.enums.Currency.DKK:
                return "\u006b\u0072"; // kr
            case nsbase.enums.Currency.NOK:
                return "\u006b\u0072"; // kr
            case nsbase.enums.Currency.SEK:
                return "\u006b\u0072"; // kr
            case nsbase.enums.Currency.HUF:
                return "\u0046\u0074"; // Ft
            case nsbase.enums.Currency.CHF:
                return "\u0043\u0048\u0046"; // CHF
            case nsbase.enums.Currency.GBP:
                return "\u00a3"; // £
            case nsbase.enums.Currency.CAD:
                return "\u0024"; // $
            case nsbase.enums.Currency.GTQ:
                return "\u0051"; // Q
            case nsbase.enums.Currency.SVC:
                return "\u0024"; // $
            case nsbase.enums.Currency.HNL:
                return "\u004c"; // L
            case nsbase.enums.Currency.CRC:
                return "\u20a1"; // ₡
            case nsbase.enums.Currency.PAB:
                return "\u0042\u002f\u002e"; // B/.
            case nsbase.enums.Currency.CUP:
                return "\u20b1"; // ₱
            case nsbase.enums.Currency.BSD:
                return "\u0024"; // $
            case nsbase.enums.Currency.JMD:
                return "\u004a\u0024"; // J$
            case nsbase.enums.Currency.DOP:
                return "\u0052\u0044\u0024"; // RD$
            case nsbase.enums.Currency.TTD:
                return "\u0054\u0054\u0024"; // TT$
            case nsbase.enums.Currency.BBD:
                return "\u0024"; // $
            case nsbase.enums.Currency.COP:
                return "\u0024"; // $
            case nsbase.enums.Currency.GYD:
                return "\u0024"; // $
            case nsbase.enums.Currency.CLP:
                return "\u0024"; // $
            case nsbase.enums.Currency.PYG:
                return "\u0047\u0073"; // Gs
            case nsbase.enums.Currency.EGP:
                return "\u00a3"; // £
            case nsbase.enums.Currency.LRD:
                return "\u0024"; // $
            case nsbase.enums.Currency.GHC:
                return "\u00a2"; // ¢
            case nsbase.enums.Currency.NGN:
                return "\u20a6"; // ₦
            case nsbase.enums.Currency.ZAR:
                return "\u0052"; // R
            case nsbase.enums.Currency.SOS:
                return "\u0053"; // S
            case nsbase.enums.Currency.SCR:
                return "\u20a8"; // ₨
            case nsbase.enums.Currency.MUR:
                return "\u20a8"; // ₨
            case nsbase.enums.Currency.ZWD:
                return "\u005a\u0024"; // Z$
            case nsbase.enums.Currency.AUD:
                return "\u0024"; // $
            case nsbase.enums.Currency.NZD:
                return "\u0024"; // $
            case nsbase.enums.Currency.FJD:
                return "\u0024"; // $
            case nsbase.enums.Currency.SBD:
                return "\u0024"; // $
            default:
                return currency;
        }
    };

    function wordLengthCounter(textContainer, wordLengthCounter, maxLength,
        isPreventMore, counterTextModifier, textLengthModifier) {
        // / <summary>
        // / count word lengh
        // / </summary>
        // / <param name="textContainer" type="jQuery">含有文字的元素</param>
        // / <param name="wordLengthCounter" type="jQuery">存放提示文字的元素</param>
        // / <param name="maxLength" type="number">最大长度</param>
        // / <param name="isPreventMore" type="bool">在超长时是否阻止输入</param>
        // / <param name="counterTextModifier"
        // type="function">对提示文字的改变规则,参数依次为currentLength和maxLength，返回一段文本</param>
        // / <param name="textLengthModifier"
        // type="function">对字符串长度的改变规则，参数为当前的文本对象,最终要求返回一个数字</param>
        textContainer.keyup(function() {
            var me = $(this);
            var currentText = me.val();
            var currentLength = textLengthModifier == null ? currentText.length
            : textLengthModifier(currentText);
            currentLength = parseInt(currentLength);
            if (currentLength == "NaN") {
                Error("Type of the return value in textLengthModifier should be a number!")
            }
            if (currentLength > maxLength) {
                if (isPreventMore) {
                    currentText.substr(0, maxLength);
                    me.text(currentText);
                }
            }
            currentLength = currentText.length;
            var tipText = counterTextModifier == null ? maxLength
            - currentLength : counterTextModifier(
                currentLength, maxLength);
            wordLengthCounter.text(tipText);
        });

    };

    function stringFormat(formatStr, arg1, arg2) {
        // / <summary>
        // / Format string with multiple arguments.
        // / </summary>
        // / <param name="formatStr" type="String">The string format.</param>
        // / <param name="arg1" type="String">The arguments.</param>
        // / <param name="arg2" type="String">More arguments.</param>
        if (arguments.length == 1) {
            return formatStr;
        }
        var formatArgs = Array.prototype.slice.call(arguments, 1);
        return formatStr.replace(/\{(\d+)\}/g, function(substr, index) {
            return formatArgs[index];
        });
    };

    function getQueryParams(name) {
        var r = new RegExp("(\\?|#|&)" + name + "=([^&#]*)(&|#|$)");
        var m = location.href.match(r);
        if(!m){
            r=new RegExp("(/)" + name + "/([^&#/]*)(/)");
            m=location.href.match(r);
        }
        return decodeURIComponent(!m ? "" : m[2]);
    };
    
    function tmplFormat(tmpl,data,formatHandler){
        return t_f(tmpl,data,-1,-1,formatHandler);
    }
    function _f(d,c,k1,k2,l){
        var q = c.match(/(first:|last:)(\"|\'*)([^\"\']*)(\"|\'*)/);
        if(!q) return "";
        if(q[1]==k1){
            if(q[2]=='\"'||q[2]=='\''){
                return q[3];
            }
            else
                return d[q[3]];
        }
        else if(q[1]==k2 && l>1){
            return "";	
        }
        return "";
    }
    function t_f(t,d,i,l,fn){
        return t.replace( /\$\{([^\}]*)\}/g,function(m,c){
            if(c.match(/index:/)){ 
                return i;
            }
            if(c.match(/fn:/) && fn){
                return fn(d,c.match(/fn:(.*)/)[1]);
            }
            if(i==0){
                var s=_f(d,c,"first:","last:",l);
                if(s) return s;
            }
            if(i==(l-1)){
                var s= _f(d,c,"last:","first:",l);
                if(s) return s;
            }
            var ar=c.split('.');
            var res=d;
            for(var key in ar)
                res=res[ar[key]];
            return res||"";
        });
    }
    
    //get string length: param1:the string param2:is uncode length default false
    function getStringLength(str,isUnicode){
        if (!str) {
            return 0;
        }
        var unicodeChars = str.match(/[^\x00-\xff]/g);
        var unicodeLength = str.length + (unicodeChars ? unicodeChars.length : 0);
        if(!isUnicode){
            return Math.ceil(unicodeLength/2);
        }
        return unicodeLength;
    }
    
    function subString(str,length){
        if(str){
            var charLength = 0;
            var reg = /[^\x00-\xff]/g;
            for (var i = 0; i < str.length; i++){
                var sonStrs = str.charAt(i).match(reg);
                if(sonStrs && sonStrs.length>0){
                    charLength += 1;
                } else {
                    charLength += 0.5;
                }
                if (charLength >= length){
                    var subLen = charLength == length ? i+1 : i;
                    return trim(str.substr(0, subLen));
                    break;
                }
            }
        }

        return "";
    }
    function getBackgroundImage (backgroundValue) {
        if(backgroundValue){
            var reg = /.*background[^;"]+url\(['|"]?([^\)|'|"]+)['|"]?\).*/gi;
            //var reg = /.*url\(['|"]([^\)]+)['|"]\).*/gi;
            var imgPath = trim(backgroundValue.replace(reg,'$1'));
            if(imgPath){
                return imgPath;
            }
        }

        return "";
    }
    _init();
}();